package com.rambler.fileupload.service.impl;

import com.rambler.common.utils.FileUtil;
import com.rambler.common.utils.IDUtil;
import com.rambler.fileupload.config.FileUploadConfig;
import com.rambler.api.fileupload.dto.FileUploadDTO;
import com.rambler.fileupload.entity.SysFileInfo;
import com.rambler.fileupload.service.FileUploadService;
import com.rambler.api.fileupload.vo.FileUploadVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Objects;

/**
 * @author suhao
 */
@Slf4j
@Service
public class LocalFileUploadServiceImpl implements FileUploadService {

    @Resource
    private FileUploadConfig fileUploadConfig;

    @Override
    public SysFileInfo uploadFile(MultipartFile file, String path, FileUploadDTO dto) {
        // 根据业务模块写到具体文件夹下
        String fileId = IDUtil.randomUUID();
        String newFileName = fileId + "." + FileUtil.getExtension(Objects.requireNonNull(file.getOriginalFilename()));
        String destFullPath = writeFile2Local(file, newFileName, path);

        // 文件写入完成后，写数据库
        SysFileInfo fileInfo = new SysFileInfo();
        fileInfo.setId(fileId);
        fileInfo.setFileKey(fileId);
        fileInfo.setStorageType("local");
        fileInfo.setStoragePath(destFullPath);
        fileInfo.setIsPublic(1);
        fileInfo.setBizType(path);
        return fileInfo;
    }

    @Override
    public List<FileUploadVO> batchUploadFile(List<MultipartFile> files, String path, FileUploadDTO dto) {
        return List.of();
    }

    @Override
    public Boolean deleteFile(String fileId) {
        return null;
    }

    @Override
    public FileUploadVO getFileInfo(String fileId) {
        return null;
    }

    @Override
    public void deleteBatch(List<String> fileIds) {

    }

    @Override
    public boolean exists(String fileId) {
        return false;
    }

    @Override
    public boolean supports(String uploadType) {
        return "local".equalsIgnoreCase(uploadType);
    }

    /**
     * 将文件写到服务器端
     *
     * @param file        文件
     * @param newFileName 新文件名称
     * @param bizName     业务名称
     */
    private String writeFile2Local(MultipartFile file, String newFileName, String bizName) {
        if ("".equals(bizName)) {
            bizName = "root";
        }
        String destFullPath = fileUploadConfig.getLocal().getSavePath() + File.separator + bizName + File.separator + newFileName;
        File destFile = new File(destFullPath);
        // 确保目录存在
        if (!destFile.getParentFile().exists()) {
            boolean mkdir = destFile.getParentFile().mkdirs();
            if (!mkdir) {
                log.info("创建文件夹失败");
            } else {
                log.info("创建文件夹成功");
            }
        }

        try (
                InputStream inputStream = file.getInputStream();
                OutputStream outputStream = new FileOutputStream(destFile)
        ) {
            // 8KB 缓冲
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            return destFullPath;
        } catch (Exception e) {
            throw new RuntimeException("文件保存失败", e);
        }
    }
}
